﻿using System;
using System.Collections.Generic;

namespace Algorytm
{
    public class Algorytm_Tworzenie_dla_Uczelni
    {
        int liczba_nauczycieli;
        int liczba_przedmiotow;
        static public int liczba_grup_przedmiotow = 0;
        int liczba_sal;
        private int suma_wywolan = 0;
        static public int liczba_dni = 2;
        static public int liczba_godzin_w_dniu = 3;
        Algorytm_Wierzcholek zrodlo;
        Algorytm_Wierzcholek ujscie;
        Algorytm_Kolejka kolejka;
        static public int MIN_PRIO = -100;
        static public Algorytm_Wyniki wyniki = new Algorytm_Wyniki();

        List<Algorytm_Nauczyciel> lista_nauczycieli = new List<Algorytm_Nauczyciel>();
        List<Algorytm_Sala> lista_sal = new List<Algorytm_Sala>();
        List<Algorytm_Przedmiot> lista_przedmiotow = new List<Algorytm_Przedmiot>();
        List<Algorytm_Grupa_Przedmiotow> list_grup_przedmiotow = new List<Algorytm_Grupa_Przedmiotow>();
        List<Algorytm_Wierzcholek> lista_wierzcholkow = new List<Algorytm_Wierzcholek>();

        public Algorytm_Tworzenie_dla_Uczelni(int l_nauczycieli, int l_przedmiotow, int l_grup_przedmitow, int l_sal, int l_dni, int l_godzin)
        {
            wyniki.czysc();
            liczba_nauczycieli = l_nauczycieli;
            liczba_przedmiotow = l_przedmiotow;
            liczba_sal = l_sal;
            liczba_grup_przedmiotow = l_grup_przedmitow;
            liczba_dni = l_dni + 1;
            liczba_godzin_w_dniu = l_godzin;
            kolejka = new Algorytm_Kolejka();
        }

        static public Algorytm_Element_Planu[][] Init_tab()
        {
            Algorytm_Element_Planu[][] tab = new Algorytm_Element_Planu[Algorytm_Tworzenie_dla_Uczelni.liczba_dni][];
            for (int i = 0; i < Algorytm_Tworzenie_dla_Uczelni.liczba_dni; i++)
            {
                tab[i] = new Algorytm_Element_Planu[Algorytm_Tworzenie_dla_Uczelni.liczba_godzin_w_dniu];
            }
            for (int i = 0; i < Algorytm_Tworzenie_dla_Uczelni.liczba_dni; i++)
            {
                for (int j = 0; j < Algorytm_Tworzenie_dla_Uczelni.liczba_godzin_w_dniu; j++)
                {
                    tab[i][j] = new Algorytm_Element_Planu();
                    tab[i][j].Usun();
                }
            }
            return tab;
        }

        private void uzupelnij_wyniki()
        {
            foreach (var item in lista_nauczycieli)
            {
                item.dodaj_do_planu();
            }
        }

        public void start()
        {
            polacz_przedmioty_z_grupami();
            zlicz_godziny_nauczycieli();
            tworzenie_wierzcholkow();
            tworzenie_grafu();
            go_go();
            uzupelnij_wyniki();
        }

        private void go_go()
        {
            bool dzialaj = true;
            int licznik = -1;
            while (dzialaj)
            {
                licznik++;
                foreach (var item in lista_wierzcholkow)
                {
                    item.czysc_zmienne();
                }
                dzialaj = znajdz_sciezke(0);
                if (!dzialaj)
                {
                    foreach (var krawedz in lista_wierzcholkow[0].krawedzie)
                    {
                        if (krawedz.pelna()) continue;
                        foreach (var item in lista_wierzcholkow)
                        {
                            item.czysc_zmienne();
                        }
                        lista_wierzcholkow[krawedz.cel].odwiedzony = true;
                        lista_wierzcholkow[krawedz.cel].krawedz_dodajaca = krawedz;
                        dzialaj = znajdz_sciezke(krawedz.cel);
                        if (dzialaj) break;
                    }
                }
            }
            p(licznik + "/" + suma_wywolan);
            if (licznik != suma_wywolan)
                wyniki.Dodaj_komentarz("nie udalo sie utworzyc calego planu", false);
            else
                wyniki.Dodaj_komentarz("Udalo sie ", true);
        }

        private bool znajdz_sciezke(int numereczek)
        {
            List<int> lista_pom = new List<int>();
            kolejka.wyczysc();
            kolejka.dodaj(numereczek, 1);
            int wierz, przynaleznosc;
            int cel, prio;
            Algorytm_Krawedz kraw;
            Algorytm_Wierzcholek wWierz, wCel;
            bool nauczyciel_moze, grupa_moze, sala_moze;
            bool dzialaj = true;
            int p1, p2;
            lista_wierzcholkow[0].odwiedzony = true;
            while (dzialaj && !kolejka.pusta())
            {
                wierz = kolejka.zdejmij();
                wWierz = lista_wierzcholkow[wierz];
                p1 = wWierz.poziom;

                foreach (var krawedz in wWierz.krawedzie)
                {
                    if (krawedz.pelna()) continue;
                    cel = krawedz.cel;
                    wCel = lista_wierzcholkow[cel];
                    //p("sprawdzam sciezke z " + wierz + " do cel " + cel);
                    if (wCel.odwiedzony) continue;
                    if (cel == ujscie.pozycja_w_liscie)
                    {
                        dzialaj = false;
                        ujscie.krawedz_dodajaca = krawedz;
                        break;
                    }
                    wCel.zmien_liste(wWierz.obecnie_rozwazane);
                    p2 = wCel.poziom;
                    if (p1 == 1 && p2 == 2)
                    {
                        nauczyciel_moze = Daj_Nauczyciela(wWierz.wartosc1).czy_moze_miec_zajecia(wCel.wartosc2, wCel.wartosc3,
                            Daj_Przedmiot(wWierz.wartosc2).dlugosc, liczba_godzin_w_dniu);
                        if (nauczyciel_moze) nauczyciel_moze = !wCel.Sprawdz_czy_jest_w_rozwazanych(1, wWierz.wartosc1, wCel.wartosc2, wCel.wartosc3, Daj_Przedmiot(wWierz.wartosc2).dlugosc, -1);
                        if (!nauczyciel_moze) nauczyciel_moze = wCel.Sprawdz_czy_jest_w_rozwazanych(1, wWierz.wartosc1, wCel.wartosc2, wCel.wartosc3, Daj_Przedmiot(wWierz.wartosc2).dlugosc, 1);
                        grupa_moze = true;
                        sala_moze = Daj_Sale(wCel.wartosc1).Czy_sala_jest_wolna_do_zajecia(wCel.wartosc2, wCel.wartosc3,
                          Daj_Przedmiot(wWierz.wartosc2).dlugosc);
                        if (sala_moze) sala_moze = !wCel.Sprawdz_czy_jest_w_rozwazanych(3, wWierz.wartosc1, wCel.wartosc2, wCel.wartosc3, Daj_Przedmiot(wWierz.wartosc2).dlugosc, -1);
                        if (!sala_moze) sala_moze = wCel.Sprawdz_czy_jest_w_rozwazanych(3, wWierz.wartosc1, wCel.wartosc2, wCel.wartosc3, Daj_Przedmiot(wWierz.wartosc2).dlugosc, 1);
                        przynaleznosc = Daj_Przedmiot(wWierz.wartosc2).przynaleznosc;
                        if (przynaleznosc > -1)
                        {
                            grupa_moze = Daj_Grupe_Przedmiotow(przynaleznosc).czy_moga_byc_zajecia(wCel.wartosc2, wCel.wartosc3,
                                Daj_Przedmiot(wWierz.wartosc2).dlugosc);
                            if (grupa_moze) grupa_moze = !wCel.Sprawdz_czy_jest_w_rozwazanych(2, wWierz.wartosc1, wCel.wartosc2, wCel.wartosc3, Daj_Przedmiot(wWierz.wartosc2).dlugosc, -1);
                            if (!grupa_moze) grupa_moze = wCel.Sprawdz_czy_jest_w_rozwazanych(2, wWierz.wartosc1, wCel.wartosc2, wCel.wartosc3, Daj_Przedmiot(wWierz.wartosc2).dlugosc, 1);
                        }

                        if (wCel.skojarzenie1 != -1)
                        {
                            if (lista_wierzcholkow[wCel.skojarzenie1].wartosc1 != wWierz.wartosc1)
                            {
                                if (!nauczyciel_moze) continue;
                            }
                            if (przynaleznosc > -1 && Daj_Przedmiot(lista_wierzcholkow[wCel.skojarzenie1].wartosc2).przynaleznosc > -1)
                            {
                                if (przynaleznosc != Daj_Przedmiot(lista_wierzcholkow[wCel.skojarzenie1].wartosc2).przynaleznosc)
                                {
                                    if (!grupa_moze) continue;
                                }
                            }
                            wCel.dodaj_do_rozwazanych(1, wWierz.wartosc1,
                            wCel.wartosc2, wCel.wartosc3, Daj_Przedmiot(wWierz.wartosc2).dlugosc, -1);
                            if (przynaleznosc > -1)
                            {
                                wCel.dodaj_do_rozwazanych(2, przynaleznosc,
                                wCel.wartosc2, wCel.wartosc3, Daj_Przedmiot(wWierz.wartosc2).dlugosc, -1);
                            }
                        }

                        {
                            if (!nauczyciel_moze || !grupa_moze || !sala_moze) continue;
                        }

                        //p("wartosci " + nauczyciel_moze + " " + grupa_moze + " " + sala_moze);

                        //                        p("pozwolilem na " + Daj_Przedmiot(wWierz.wartosc2).dlugosc + " w dzien " + wCel.wartosc2 + " godz " + wCel.wartosc3);
                    }
                    else
                        if (p1 == 2 && p2 == 1)
                        {
                            wCel.dodaj_do_rozwazanych(1, lista_wierzcholkow[wWierz.skojarzenie1].wartosc1,
                                    wWierz.wartosc2, wWierz.wartosc3, Daj_Przedmiot(wCel.wartosc2).dlugosc, 1);
                            if (Daj_Przedmiot(wCel.wartosc2).przynaleznosc > -1)
                                wCel.dodaj_do_rozwazanych(2, Daj_Przedmiot(wCel.wartosc2).przynaleznosc,
                                    wWierz.wartosc2, wWierz.wartosc3, Daj_Przedmiot(wCel.wartosc2).dlugosc, 1);
                        }
                    prio = oblicz_priorytet(lista_wierzcholkow[wierz], lista_wierzcholkow[cel]);
                    if (prio == MIN_PRIO) continue;
                    lista_wierzcholkow[cel].odwiedzony = true;
                    lista_wierzcholkow[cel].krawedz_dodajaca = krawedz;
                    //p("Wierz: " + wierz + " wrzuca Cel: " + cel);
                    kolejka.dodaj(cel, prio);
                }
            }
            if (dzialaj) return false;
            lista_pom.Add(ujscie.pozycja_w_liscie);
            kraw = ujscie.krawedz_dodajaca;
            wierz = kraw.skad;
            while (wierz != 0)
            {
                lista_pom.Add(wierz);
                kraw = lista_wierzcholkow[wierz].krawedz_dodajaca;
                wierz = kraw.skad;
            }
            lista_pom.Reverse();

            //for (int i = 0; i < lista_pom.Count; i++)
            //{
            //    Console.Write(lista_pom[i] + " ");
            //}
            //p("  --------------------------------");
            p1 = -1; p2 = -1;
            Algorytm_Wierzcholek wierzch;
            for (int i = 0; i < lista_pom.Count; i++)
            {
                wierzch = lista_wierzcholkow[lista_pom[i]];
                wierzch.krawedz_dodajaca.pusc_przeplyw();
                if (wierzch.poziom == 1)
                {
                    p1 = lista_pom[i];
                }
                else
                    if (wierzch.poziom == 2)
                    {
                        p2 = lista_pom[i];
                        p1 = dodaj_skojarzenie(p1, p2, Daj_Przedmiot(lista_wierzcholkow[p1].wartosc2).dlugosc);
                    }
            }
            return true;
        }

        private int oblicz_priorytet(Algorytm_Wierzcholek a, Algorytm_Wierzcholek b)
        {
            if (a.poziom == 0 || b.poziom == 4) return 10;
            if (a.poziom == 1 && b.poziom == 2)
            {
                return Daj_Nauczyciela(a.wartosc1).policz_priorytet(b.wartosc2, b.wartosc3, Daj_Przedmiot(a.wartosc2).dlugosc);
            }
            else
                if (a.poziom == 2 && b.poziom == 1)
                {
                    return Daj_Nauczyciela(b.wartosc1).policz_priorytet_usuniecia(a.wartosc2, a.wartosc3, Daj_Przedmiot(b.wartosc2).dlugosc);
                }
            return MIN_PRIO;
        }

        private int dodaj_skojarzenie(int w1, int w2, int dlugosc)
        {
            int dzien = lista_wierzcholkow[w2].wartosc2;
            int godzina = lista_wierzcholkow[w2].wartosc3;
            int pom1 = w1;
            Algorytm_Przedmiot przedmiot = Daj_Przedmiot(lista_wierzcholkow[w1].wartosc2);
            if (lista_wierzcholkow[w2].skojarzenie1 != -1)
            {
                pom1 = lista_wierzcholkow[w2].skojarzenie1;
                usun_skojarzenie(w1, dzien, godzina, dlugosc);
                usun_skojarzenie(w2, dzien, godzina, dlugosc);
                lista_wierzcholkow[w2].skojarzenie1 = -1;
            }

            Algorytm_Element_Planu element = new Algorytm_Element_Planu(0,
                lista_wierzcholkow[w1].wartosc1, lista_wierzcholkow[w1].wartosc2,
                lista_wierzcholkow[w2].wartosc1, przedmiot.dlugosc,
                przedmiot.liczba_grup > 1);
            if (przedmiot.przynaleznosc > -1)
                Daj_Grupe_Przedmiotow(przedmiot.przynaleznosc).Dodaj_skojarzenie(element, dzien, godzina, dlugosc);
            Daj_Nauczyciela(lista_wierzcholkow[w1].wartosc1).Dodaj_skojarzenie(element, dzien, godzina, dlugosc);
            Daj_Sale(lista_wierzcholkow[w2].wartosc1).Dodaj_skojarzenie(element, dzien, godzina, dlugosc);
            lista_wierzcholkow[w2].skojarzenie1 = w1;
            //if (czy && czy2) lista_wierzcholkow[w3].podwojny = true;
            return pom1;
        }

        public void dodaj_nieobecnosc_nauczyciela(int numer_nauczyciela, Algorytm_Przedzial przedzial)
        {
            Daj_Nauczyciela(numer_nauczyciela).Dodaj_zly_przedzial(przedzial);
        }

        public void dodaj_niedostepnosc_sali(int numer_sali, Algorytm_Przedzial przedzial)
        {
            Daj_Sale(numer_sali).dodaj_zly_przedzial(przedzial);
        }

        public void Ustaw_obecny_plan(List<Algorytm_Element_wyniku> lista)
        {
            wyniki.czysc();
            Algorytm_Element_Planu element;
            int dzien, godzina;
            wyniki.Ustaw_liste(lista);
            foreach (var item in lista)
            {
                dzien = item.Dzien;
                godzina = item.Godzina;
                element = new Algorytm_Element_Planu(item.Klasa, item.Nauczyciel, item.Przedmiot, item.Sala, item.Dlugosc, item.Czy_zajecia_sa_grupowe);
                if (Daj_Przedmiot(item.Przedmiot).przynaleznosc != -1)
                    Daj_Grupe_Przedmiotow(Daj_Przedmiot(item.Przedmiot).przynaleznosc).Dodaj_skojarzenie(element, dzien, godzina, item.Dlugosc);
                Daj_Nauczyciela(item.Nauczyciel).Dodaj_skojarzenie(element, dzien, godzina, item.Dlugosc);
                Daj_Sale(item.Sala).Dodaj_skojarzenie(element, dzien, godzina, item.Dlugosc);
            }
        }

        public void Generuj_plan_awaryjny()
        {
            List<Algorytm_Element_Planu> lista;
            bool czy;
            bool czy_wszystko_ok = true;
            for (int i = 0; i < liczba_dni; i++)
            {
                foreach (var item in lista_nauczycieli)
                {
                    lista = item.Zwroc_przedmioty_do_zamiany(i);
                    foreach (var item2 in lista)
                    {
                        if (Daj_Przedmiot(item2.przedmiot).przynaleznosc != -1)
                            Daj_Grupe_Przedmiotow(Daj_Przedmiot(item2.przedmiot).przynaleznosc).Usun_skojarzenie(item2.dzien, item2.godzina, item2.dlugosc);
                        Daj_Nauczyciela(item2.nauczyciel).Usun_skojarzenie(item2.dzien, item2.godzina, item2.dlugosc);
                        Daj_Sale(item2.sala).Usun_skojarzenie(item2.dzien, item2.godzina, item2.dlugosc);
                    }
                    foreach (var item2 in lista)
                    {
                        czy = Daj_Sale(item2.sala).sprawdz_czy_jest_w_zlym_przedziale(i, item2.godzina, item2.dlugosc);
                        czy_wszystko_ok = Dodaj_do_nowego_planu(item2, true, czy);
                        if (!czy_wszystko_ok) break;
                    }
                    if (!czy_wszystko_ok) break;
                }
                if (!czy_wszystko_ok) break;
                foreach (var item in lista_sal)
                {
                    lista = item.Zwroc_przedmioty_do_zamiany(i);
                    foreach (var item2 in lista)
                    {
                        if (Daj_Przedmiot(item2.przedmiot).przynaleznosc != -1)
                            Daj_Grupe_Przedmiotow(Daj_Przedmiot(item2.przedmiot).przynaleznosc).Usun_skojarzenie(item2.dzien, item2.godzina, item2.dlugosc);
                        Daj_Nauczyciela(item2.nauczyciel).Usun_skojarzenie(item2.dzien, item2.godzina, item2.dlugosc);
                        Daj_Sale(item2.sala).Usun_skojarzenie(item2.dzien, item2.godzina, item2.dlugosc);
                    }
                    foreach (var item2 in lista)
                    {
                        czy_wszystko_ok = Dodaj_do_nowego_planu(item2, false, true);
                        if (!czy_wszystko_ok) break;
                    }
                    if (!czy_wszystko_ok) break;
                }
                if (!czy_wszystko_ok) break;
            }
            wyniki.czysc();
            uzupelnij_wyniki_do_planu_awaryjnego();
            wyniki.Czy_wszystko_poszlo_dobrze = czy_wszystko_ok;
            if (!czy_wszystko_ok) wyniki.Dodaj_komentarz("Tworzenie Planu Awaryjnego nie powiodło się...", false);
            else wyniki.Dodaj_komentarz("Plan Awaryjny wygenerowany pomyślnie...", true);
        }

        private void uzupelnij_wyniki_do_planu_awaryjnego()
        {
            foreach (var item in lista_nauczycieli)
            {
                item.dodaj_do_planu_awaryjnego();
            }
        }

        private bool Dodaj_do_nowego_planu(Algorytm_Element_Planu _elem, bool nauczyciel, bool sala)
        {
            Algorytm_Element_Planu elem = new Algorytm_Element_Planu(_elem);
            if (nauczyciel && !sala)
            {
                foreach (var item in lista_nauczycieli)
                {
                    if (item.sprawdz_czy_jest_w_zlym_przedziale(elem.dzien, elem.godzina, elem.dlugosc)) continue;
                    if (!item.czy_ucze_tego_na_studiach(elem.przedmiot)) continue;
                    if (item.czy_moze_miec_zajecia(elem.dzien, elem.godzina, elem.dlugosc, liczba_godzin_w_dniu))
                    {
                        elem.nauczyciel = item.numer;
                        elem.czy_jest_z_awaryjnego = true;
                        if (Daj_Przedmiot(elem.przedmiot).przynaleznosc != -1)
                            Daj_Grupe_Przedmiotow(Daj_Przedmiot(elem.przedmiot).przynaleznosc).Dodaj_skojarzenie_do_planu_awaryjnego(elem, elem.dzien, elem.godzina, elem.dlugosc);
                        Daj_Nauczyciela(item.numer).Dodaj_skojarzenie_do_planu_awaryjnego(elem, elem.dzien, elem.godzina, elem.dlugosc);
                        Daj_Sale(elem.sala).Dodaj_skojarzenie_do_planu_awaryjnego(elem, elem.dzien, elem.godzina, elem.dlugosc);

                        return true;
                    }
                }
            }
            if (nauczyciel && sala)
            {
                foreach (var item in lista_nauczycieli)
                {
                    if (item.sprawdz_czy_jest_w_zlym_przedziale(elem.dzien, elem.godzina, elem.dlugosc)) continue;
                    if (!item.czy_ucze_tego_na_studiach(elem.przedmiot)) continue;
                    if (item.czy_moze_miec_zajecia(elem.dzien, elem.godzina, elem.dlugosc, liczba_godzin_w_dniu))
                    {
                        foreach (var item2 in lista_sal)
                        {
                            if (item2.sprawdz_czy_jest_w_zlym_przedziale(elem.dzien, elem.godzina, elem.dlugosc)) continue;
                            if (!item2.Czy_sala_jest_wolna(elem.dzien, elem.godzina, elem.dlugosc, liczba_godzin_w_dniu)) continue;
                            if (!Daj_Nauczyciela(item.numer).czy_moze_miec_zajecia(elem.dzien, elem.godzina, elem.dlugosc, liczba_godzin_w_dniu)) continue;
                            elem.nauczyciel = item.numer;
                            elem.sala = item2.numer;
                            elem.czy_jest_z_awaryjnego = true;
                            if (Daj_Przedmiot(elem.przedmiot).przynaleznosc != -1)
                                Daj_Grupe_Przedmiotow(Daj_Przedmiot(elem.przedmiot).przynaleznosc).Dodaj_skojarzenie_do_planu_awaryjnego(elem, elem.dzien, elem.godzina, elem.dlugosc);
                            Daj_Nauczyciela(elem.nauczyciel).Dodaj_skojarzenie_do_planu_awaryjnego(elem, elem.dzien, elem.godzina, elem.dlugosc);
                            Daj_Sale(elem.sala).Dodaj_skojarzenie_do_planu_awaryjnego(elem, elem.dzien, elem.godzina, elem.dlugosc);
                            return true;
                        }
                    }
                }
            }
            if (!nauczyciel && sala)
            {
                foreach (var item in lista_sal)
                {
                    if (item.sprawdz_czy_jest_w_zlym_przedziale(elem.dzien, elem.godzina, elem.dlugosc)) continue;
                    if (!item.Czy_sala_jest_wolna(elem.dzien, elem.godzina, elem.dlugosc, liczba_godzin_w_dniu)) continue;
                    elem.sala = item.numer;
                    elem.czy_jest_z_awaryjnego = true;
                    if (Daj_Przedmiot(elem.przedmiot).przynaleznosc != -1)
                        Daj_Grupe_Przedmiotow(Daj_Przedmiot(elem.przedmiot).przynaleznosc).Dodaj_skojarzenie_do_planu_awaryjnego(elem, elem.dzien, elem.godzina, elem.dlugosc);
                    Daj_Nauczyciela(elem.nauczyciel).Dodaj_skojarzenie_do_planu_awaryjnego(elem, elem.dzien, elem.godzina, elem.dlugosc);
                    Daj_Sale(elem.sala).Dodaj_skojarzenie_do_planu_awaryjnego(elem, elem.dzien, elem.godzina, elem.dlugosc);
                    return true;
                }
            }
            return false;
        }

        private void tworzenie_wierzcholkow()
        {
            utworz_zrodlo();
            utworz_wierzcholki_nauczycieli();
            utworz_wierzcholki_sal();
            utworz_ujscie();
        }

        private void tworzenie_grafu()
        {
            utworz_krawedzie_zrodlo_nauczyciele();
            utworz_krawedzie_nauczyciele_sale();
            utworz_krawedzie_sale_ujscie();
        }

        private void usun_skojarzenie(int w1, int dzien, int godz, int dlugosc)
        {
            if (lista_wierzcholkow[w1].poziom == 1)
            {
                Algorytm_Przedmiot przed = Daj_Przedmiot(lista_wierzcholkow[w1].wartosc2);
                if (przed.przynaleznosc > -1)
                    Daj_Grupe_Przedmiotow(przed.przynaleznosc).Usun_skojarzenie(dzien, godz, dlugosc);
                Daj_Nauczyciela(lista_wierzcholkow[w1].wartosc1).Usun_skojarzenie(dzien, godz, dlugosc);
            }
            if (lista_wierzcholkow[w1].poziom == 1)
            {
                Daj_Sale(lista_wierzcholkow[w1].wartosc1).Usun_skojarzenie(dzien, godz, dlugosc);
            }
        }

        private void utworz_zrodlo()
        {
            zrodlo = new Algorytm_Wierzcholek(0);
            lista_wierzcholkow.Add(zrodlo);
        }

        private void utworz_ujscie()
        {
            ujscie = new Algorytm_Wierzcholek(4);
            ujscie.pozycja_w_liscie = lista_wierzcholkow.Count;
            lista_wierzcholkow.Add(ujscie);
        }

        private void polacz_przedmioty_z_grupami()
        {
            foreach (var item in list_grup_przedmiotow)
            {
                foreach (var item2 in item.lista_przedmiotow)
                {
                    Daj_Przedmiot(item2).przynaleznosc = item.numer;
                }
            }
        }

        private void zlicz_godziny_nauczycieli()
        {
            foreach (var item in lista_nauczycieli)
            {
                item.Zlicz_laczna_liczbe_godzin();
            }
        }

        private void utworz_wierzcholki_nauczycieli()
        {
            for (int i = 0; i < lista_nauczycieli.Count; i++)
            {
                foreach (var item in lista_nauczycieli[i].przedmioty_studia)
                {
                    lista_wierzcholkow.Add(new Algorytm_Wierzcholek(1, i, lista_nauczycieli[i].numer, item.numer, item.ilosc_wystapien));
                }
            }
        }

        public Algorytm_Wyniki Pobierz_Plan()
        {
            Algorytm_Wyniki wyn = new Algorytm_Wyniki(wyniki);
            return wyn;
        }

        private void utworz_wierzcholki_sal()
        {
            for (int i = 0; i < lista_sal.Count; i++)
            {
                for (int dzien = 0; dzien < liczba_dni; dzien++)
                {
                    for (int godzina = 0; godzina < liczba_godzin_w_dniu; godzina++)
                    {
                        lista_wierzcholkow.Add(new Algorytm_Wierzcholek(2, i, lista_sal[i].numer, dzien, godzina));
                    }
                }
            }
        }

        private void utworz_krawedzie_zrodlo_nauczyciele()
        {
            int numer_zrodla = 0;
            Algorytm_Krawedz krawedz;
            for (int i = 0; i < lista_wierzcholkow.Count; i++)
            {
                if (lista_wierzcholkow[i].poziom == 0)
                {
                    numer_zrodla = i;
                    break;
                }
            }
            for (int i = 0; i < lista_wierzcholkow.Count; i++)
            {
                if (lista_wierzcholkow[i].poziom == 1)
                {
                    krawedz = new Algorytm_Krawedz(numer_zrodla, i, lista_wierzcholkow[i].wartosc3);
                    zrodlo.krawedzie.Add(krawedz);
                    suma_wywolan += lista_wierzcholkow[i].wartosc3;
                }
            }
        }

        private void utworz_krawedzie_nauczyciele_sale()
        {
            int dlugosc = 1;
            for (int i = 0; i < lista_wierzcholkow.Count; i++)
            {
                if (lista_wierzcholkow[i].poziom == 1)
                {
                    dlugosc = Daj_Przedmiot(lista_wierzcholkow[i].wartosc2).dlugosc;

                    for (int j = 0; j < lista_wierzcholkow.Count; j++)
                    {
                        if (lista_wierzcholkow[j].poziom == 2)
                        {
                            if (lista_sal[lista_wierzcholkow[j].pozycja_w_liscie].przedmioty.Contains(lista_wierzcholkow[i].wartosc2))
                            {
                                Algorytm_Wierzcholek w = lista_wierzcholkow[j];
                                if (lista_nauczycieli[lista_wierzcholkow[i].pozycja_w_liscie].czy_jest_dostepny(w.wartosc2, w.wartosc3, dlugosc))
                                {
                                    Algorytm_Krawedz krawedz = new Algorytm_Krawedz(i, j, 1);
                                    Algorytm_Krawedz krawedz2 = new Algorytm_Krawedz(j, i, 0, krawedz);
                                    krawedz.dodaj_krawedz_przeciwna(krawedz2);
                                    lista_wierzcholkow[i].krawedzie.Add(krawedz);
                                    lista_wierzcholkow[j].krawedzie.Add(krawedz2);
                                }
                            }
                        }
                    }
                }
            }
        }

        private void utworz_krawedzie_sale_ujscie()
        {
            Algorytm_Wierzcholek ujscie;
            int numer_ujscia = 0;
            for (int i = 0; i < lista_wierzcholkow.Count; i++)
            {
                if (lista_wierzcholkow[i].poziom == 4)
                {
                    ujscie = lista_wierzcholkow[i];
                    numer_ujscia = i;
                }
            }
            for (int i = 0; i < lista_wierzcholkow.Count; i++)
            {
                if (lista_wierzcholkow[i].poziom == 2)
                {
                    lista_wierzcholkow[i].krawedzie.Add(new Algorytm_Krawedz(i, numer_ujscia, 1));
                }
            }
        }

        static public void p(int a)
        {
            System.Console.WriteLine(a);
        }

        static public void p(string a)
        {
            System.Console.WriteLine(a);
        }

        private Algorytm_Sala Daj_Sale(int nr)
        {
            Algorytm_Sala sal = new Algorytm_Sala();
            foreach (var item in lista_sal)
            {
                if (item.numer == nr)
                    return item;
            }
            return sal;
        }

        private Algorytm_Nauczyciel Daj_Nauczyciela(int nr)
        {
            Algorytm_Nauczyciel nau = new Algorytm_Nauczyciel();
            foreach (var item in lista_nauczycieli)
            {
                if (item.numer == nr)
                    return item;
            }
            return nau;
        }

        private Algorytm_Przedmiot Daj_Przedmiot(int numer)
        {
            Algorytm_Przedmiot przedmiot = new Algorytm_Przedmiot();
            foreach (var item in lista_przedmiotow)
            {
                if (item.numer == numer)
                    return item;
            }
            return przedmiot;
        }

        private Algorytm_Grupa_Przedmiotow Daj_Grupe_Przedmiotow(int numer)
        {
            Algorytm_Grupa_Przedmiotow grupa = new Algorytm_Grupa_Przedmiotow();
            foreach (var item in list_grup_przedmiotow)
            {
                if (item.numer == numer)
                    return item;
            }
            return grupa;
        }

        public void Dodaj_nauczyciela(Algorytm_Nauczyciel nauczyciel)
        {
            lista_nauczycieli.Add(nauczyciel);
        }

        public void Dodaj_sale(Algorytm_Sala sala)
        {
            lista_sal.Add(sala);
        }

        public void Dodaj_przedmiot(Algorytm_Przedmiot przedmiot)
        {
            lista_przedmiotow.Add(przedmiot);
        }

        public void Dodaj_Grupe_Przedmiotow(Algorytm_Grupa_Przedmiotow grupa)
        {
            list_grup_przedmiotow.Add(grupa);
        }

        public void drukuj_graf(int a)
        {
            for (int i = 0; i < lista_wierzcholkow.Count; i++)
            {
                System.Console.Write(i);
                for (int q = 0; q < lista_wierzcholkow[i].krawedzie.Count; q++)
                {
                    if (a == 0 || (a == 1 && lista_wierzcholkow[i].krawedzie[q].przeplyw > 0))
                    {
                        System.Console.Write("->");
                        System.Console.Write(lista_wierzcholkow[i].krawedzie[q].cel + "(" + lista_wierzcholkow[i].krawedzie[q].przeplyw + "/" + lista_wierzcholkow[i].krawedzie[q].przepustowosc + ")");
                    }
                }
                System.Console.Write("\n");
            }
        }

        public void drukuj_wierzcholki()
        {
            for (int i = 0; i < lista_wierzcholkow.Count; i++)
            {
                System.Console.Write(i);
                System.Console.Write(" ");
                System.Console.Write(lista_wierzcholkow[i].poziom);
                System.Console.Write(" ");
                System.Console.Write(lista_wierzcholkow[i].wartosc1);
                System.Console.Write(" ");
                System.Console.Write(lista_wierzcholkow[i].wartosc2);
                System.Console.Write(" ");
                System.Console.Write(lista_wierzcholkow[i].wartosc3);
                System.Console.WriteLine(" ");
            }
        }

        public void drukuj_przedmioty()
        {
            foreach (var item in lista_przedmiotow)
            {
                p("przedmiot " + item.numer + " dlugosc " + item.dlugosc + " liczba_grup " + item.liczba_grup);
            }
        }

        public void drukuj_naucz()
        {
            foreach (var item in lista_nauczycieli)
            {
                item.Print();
            }
        }

        private static void Maine(string[] args)
        {
            p("start");
            int nr, prefnr, lprzed, lprzedzial, lgodz, lgrup;
            Algorytm_Przedzial[] lista;
            List<int> lista_intow = new List<int>();
            System.IO.StreamReader plik = new System.IO.StreamReader("e:\\Uczelnia1.txt");
            string sLine = "";
            int[] pomtabint;
            Algorytm_Para_Studia para;
            sLine = plik.ReadLine();
            string[] tab = sLine.Split(' ');
            int liczba_nauczycieli = int.Parse(tab[0]);
            int liczba_przedmiotow = int.Parse(tab[1]);
            int liczba_sal = int.Parse(tab[2]);
            int liczba_grup = int.Parse(tab[3]);
            int wczytana_liczba_dni = int.Parse(tab[4]);
            int liczba_godzin = int.Parse(tab[5]);
            Algorytm_Tworzenie_dla_Uczelni A = new Algorytm_Tworzenie_dla_Uczelni(liczba_nauczycieli, liczba_przedmiotow, liczba_grup, liczba_sal, wczytana_liczba_dni, liczba_godzin);
            for (int i = 0; i < liczba_nauczycieli; i++)
            {
                sLine = plik.ReadLine();
                tab = sLine.Split(' ');
                nr = int.Parse(tab[0]);
                prefnr = int.Parse(tab[1]);
                lprzed = int.Parse(tab[2]);
                List<Algorytm_Para_Studia> pomtab = new List<Algorytm_Para_Studia>();
                for (int q = 0; q < lprzed; q++)
                {
                    para = new Algorytm_Para_Studia(int.Parse(tab[3 + 2 * q]), int.Parse(tab[4 + 2 * q]));
                    pomtab.Add(para);
                }
                lprzedzial = int.Parse(tab[3 + 2 * lprzed]);
                lista = new Algorytm_Przedzial[lprzedzial];
                for (int q = 0; q < lprzedzial; q++)
                {
                    lista[q] = new Algorytm_Przedzial(int.Parse(tab[4 + 2 * lprzed + q * 3]), int.Parse(tab[5 + 2 * lprzed + q * 3]), int.Parse(tab[6 + 2 * lprzed + q * 3]));
                }
                A.Dodaj_nauczyciela(new Algorytm_Nauczyciel(nr, prefnr, lprzed, pomtab, lprzedzial, lista));
            }
            for (int i = 0; i < liczba_sal; i++)
            {
                sLine = plik.ReadLine();
                tab = sLine.Split(' ');
                nr = int.Parse(tab[0]);
                lprzed = int.Parse(tab[1]);
                pomtabint = new int[lprzed];
                for (int q = 0; q < lprzed; q++)
                {
                    pomtabint[q] = int.Parse(tab[2 + q]);
                }
                A.Dodaj_sale(new Algorytm_Sala(nr, lprzed, pomtabint, true));
            }
            for (int i = 0; i < liczba_przedmiotow; i++)
            {
                sLine = plik.ReadLine();
                tab = sLine.Split(' ');
                nr = int.Parse(tab[0]);
                lgodz = int.Parse(tab[1]);
                lgrup = int.Parse(tab[2]);
                A.Dodaj_przedmiot(new Algorytm_Przedmiot(nr, lgrup, lgodz));
            }
            for (int i = 0; i < liczba_grup_przedmiotow; i++)
            {
                sLine = plik.ReadLine();
                tab = sLine.Split(' ');
                nr = int.Parse(tab[0]);
                lprzed = int.Parse(tab[1]);
                lista_intow.Clear();
                for (int q = 0; q < lprzed; q++)
                {
                    lgodz = int.Parse(tab[2 + q]);
                    lista_intow.Add(lgodz);
                }
                A.Dodaj_Grupe_Przedmiotow(new Algorytm_Grupa_Przedmiotow(nr, lista_intow));
            }

            plik.Close();
            A.start();
            p("-------------------------");
            //A.drukuj_wierzcholki();
            //A.drukuj_graf(1);
            wyniki.Drukuj();
            //A.drukuj_przedmioty();
            p("koniec");
            Console.ReadKey();
        }
    }
}